package com.zmm.member.service.impl;

import com.zmm.common.dict.enums.RegionType;
import com.zmm.common.dict.enums.RegionVersion;
import com.zmm.common.dict.model.Region;
import com.zmm.common.mongo.key.member.RegionConstant;
import com.zmm.common.redis.key.CommonKey;
import com.zmm.member.dao.DictDao;
import com.zmm.member.service.DictService;
import com.zmm.util.redis.RedisUtil;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 900045
 * @description:
 * @name DictServiceImpl
 * @date By 2021-07-23 15:12:31
 */
@Service
public class DictServiceImpl implements DictService {

	@Resource
	private RedisUtil<Object> redisUtil;

	@Resource
	private MongoTemplate mongoTemplate;
	
	@Resource
	private DictDao dictDao;

	@Override
	public String fetchRegionName(RegionVersion regionVersion, RegionType regionType, Integer parent, Integer regionId) {
		Region region;
		if (regionVersion != null && regionVersion == RegionVersion.V2) {
			// 地址版本 2.0
			region = fetchRegion(regionVersion, regionType, parent, regionId);
		} else {
			// 地址版本 1.0
			region = fetchRegion(regionType, parent, regionId);
		}
		return region == null ? null : region.getName();
	}


	/**
	 * 获取地区对象 1.0 -- 实现
	 * @author: 900045
	 * @date: 2021-08-04 14:49:28
	 * @throws 
	 * @param regionType: 
	 * @param parent: 
	 * @param regionId: 
	 * @return: com.zmm.common.dict.model.Region
	 **/
	@Override
	public Region fetchRegion(RegionType regionType, Integer parent, Integer regionId) {
		Map<Integer, Region> regionMap = initRegion(regionType, parent);
		if (CollectionUtils.isEmpty(regionMap)) {
			return null;
		}
		return regionMap.get(regionId);
	}

	/**
	 * 获取地区对象 2.0 -- 接口
	 * @author: 900045
	 * @date: 2021-08-04 14:49:38
	 * @throws 
	 * @param regionVersion: 
	 * @param regionType: 
	 * @param parent: 
	 * @param regionId: 
	 * @return: com.zmm.common.dict.model.Region
	 **/
	@Override
	public Region fetchRegion(RegionVersion regionVersion, RegionType regionType, Integer parent, Integer regionId) {
		Map<Integer, Region> regionMap = initRegionV2(regionType, parent);
		if (CollectionUtils.isEmpty(regionMap)) {
			return null;
		}
		// TODO Map 已经指定的 key 为 Integer 但存入 redis 时为 String 
		Region region = regionMap.get(regionId.toString());
		return region;
	}


	/**
	 * 地址版本 2.0信息加载 -- 接口
	 * @author: 900045
	 * @date: 2021-08-04 14:38:50
	 * @throws 
	 * @param regionVersion: 
	 * @param regionType: 
	 * @param parent: 
	 * @return: java.util.List<com.zmm.common.dict.model.Region>
	 **/
	@Override
	public Collection<Region> queryRegionReload(RegionVersion regionVersion, RegionType regionType, Integer parent) {
		
		if (RegionVersion.V1 == regionVersion) {
			// 兼容 查询 地址版本 1.0
			return queryRegionReload(regionType, parent);
		}
		
		Map<Integer, Region> regionMap = initRegionV2(regionType,parent);
		if (CollectionUtils.isEmpty(regionMap)) {
			return null;
		}
		Collection<Region> values = regionMap.values();
		
		return values.stream().sorted(Comparator.comparing(Region::getId)).collect(Collectors.toList());
	}

	/**
	 * 地址版本 1.0 信息加载 -- 实现
	 * @author: 900045
	 * @date: 2021-08-04 14:47:01
	 * @throws 
	 * @param regionType: 
	 * @param parent: 
	 * @return: java.util.Collection<com.zmm.common.dict.model.Region>
	 **/
	@Override
	public Collection<Region> queryRegionReload(RegionType regionType, Integer parent) {
		Map<Integer, Region> regionMap = initRegion(regionType, parent);
		if (CollectionUtils.isEmpty(regionMap)) {
			return null;
		}
		return regionMap.values();
	}

	private Map<Integer, Region> initRegionV2(RegionType regionType, Integer parent) {
		parent = parent == null ? 0 : parent;
		CommonKey key = regionType.getRedisKey(RegionVersion.V2);

		//省级
		Object obj = redisUtil.hash(key, parent);
		if (obj != null && obj instanceof Map) {
			return (Map<Integer, Region>) obj;
		}

		List<Region> list = this.fetchByParent(parent);
		Map<Integer, Region> map = getRegionMap(list);
		if (ObjectUtils.isEmpty(map)) {
			return null;
		}

		redisUtil.hash(key, Integer.toString(parent), map);
		return map;
	}

	private Map<Integer, Region> getRegionMap(List<Region> list) {
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}

		//需要有序  默认ID排序
		Map<Integer, Region> map = new HashMap<Integer, Region>();

		for (Region r : list) {
			map.put(r.getId(), r);
		}
		return map;
	}

	/**
	 * 从 mongoDB 中查询地域信息
	 * @author: 900045
	 * @date: 2021-08-04 14:47:56
	 * @throws 
	 * @param parent: 
	 * @return: java.util.List<com.zmm.common.dict.model.Region>
	 **/
	private List<Region> fetchByParent(Integer parent) {
		Query query = new Query(
				// Criteria.where("parent").is(parent).and("level").is(regionType.level))
				Criteria.where("parent").is(parent));
		return mongoTemplate.find(query, Region.class, RegionConstant.COLLECTION_REGION);
	}

	/**
	 * 初始化地址
	 * @author: 900045
	 * @date: 2021-08-04 11:19:14
	 * @throws 
	 * @param regionType: 
	 * @param parent: 
	 * @return: java.util.Map<java.lang.Integer,com.zmm.common.dict.model.Region>
	 **/
	private Map<Integer, Region> initRegion(RegionType regionType, Integer parent) {
		parent = parent == null ? 0 : parent;
		Region region = new Region();
		region.setType(regionType.name());
		region.setParent(parent);

		List<Region> list = dictDao.selectRegionByParent(region);
		Map<Integer, Region> map = getRegionMap(list);
		if (ObjectUtils.isEmpty(map)) {
			return null;
		}
		return map;
	}
}
